#include <iostream>
#include <exception>

#include "interpreter.h"
#include "instructions/instruction_factory.h"

namespace jvm {

void Interpreter::interpret(std::shared_ptr<heap::Method> methodInfo) {
    // auto codeAttr = methodInfo->getCodeAttribute();
    // uint16_t maxLocals = codeAttr->getMaxLocals();
    // uint16_t maxStack = codeAttr->getMaxStack();
    // auto bytecode = codeAttr->getCode();

    auto thread = std::make_shared<rtda::Thread>();
    auto frame = thread->newFrame(methodInfo);
    thread->pushFrame(frame);

    try {
        loop(thread, methodInfo.getCode());
    } catch (...) {
        catchErr(frame);
        throw; // 重新抛出异常
    }
}

void Interpreter::catchErr(std::shared_ptr<rtda::Frame> frame) {
    try {
        std::cout << "LocalVars: ";
        frame->getLocalVars().printAll();
        std::cout << "OperandStack: ";
        frame->getOperandStack()->printAll();
    } catch (...) {
        // 确保打印错误信息时不会抛出新的异常
    }
}

void Interpreter::loop(std::shared_ptr<rtda::Thread> thread, const std::vector<uint8_t>& bytecode) {
    auto frame = thread->popFrame();
    auto reader = std::make_shared<instructions::BytecodeReader>();

    while (true) {
        uint32_t pc = frame->getNextPC();
        thread->setPC(pc);

        // 解码指令
        reader->reset(bytecode, pc);
        uint8_t opcode = reader->readUint8();
        auto inst = instructions::InstructionFactory::newInstruction(opcode);
        inst->fetchOperands(reader);
        frame->setNextPC(reader->getPc());

        // 执行指令
        std::cout << "pc:" << pc << " inst:" << typeid(*inst).name() << std::endl;
        inst->execute(frame);
    }
}

} // namespace jvm